﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Base
{
#pragma warning disable 8500

    /// <summary>
    /// 
    /// </summary>
    unsafe public partial class EnumerableEx
    {
        /// <summary>
        /// 查找T指针中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="ptr">数据指针</param>
        /// <param name="length">数据长度</param>
        /// <returns>结果</returns>
        unsafe public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(T* ptr, int length)
            where T : struct, INumber<T>
        {
            if (length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            T maxValue = ptr[0];

            for (int i = 1; i < length; i++)
            {
                if (ptr[i] > maxValue)
                {
                    maxValue = ptr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T数组中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(IEnumerable<T> arr)
             where T : struct, INumber<T>
        {
            if (arr == null)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int length = arr.Count();
            if (length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            T maxValue = arr.ElementAt(0);

            for (int i = 1; i < length; i++)
            {
                if (arr.ElementAt(i) > maxValue)
                {
                    maxValue = arr.ElementAt(i);
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T数组中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">查找的数据个数</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(IEnumerable<T> arr, int startIndex, int count)
            where T : struct, INumber<T>
        {
            if (arr == null || count < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int end = startIndex + count;
            int maxValueIndex = startIndex;
            T maxValue = arr.ElementAt(startIndex);

            for (int i = startIndex + 1; i < end; i++)
            {
                if (arr.ElementAt(i) > maxValue)
                {
                    maxValue = arr.ElementAt(i);
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T数组中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(T[] arr)
            where T : struct, INumber<T>
        {
            if (arr == null)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            T maxValue = arr[0];

            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T数组中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">查找的数据个数</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(T[] arr, int startIndex, int count)
            where T : struct, INumber<T>
        {
            if (arr == null || count < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int end = startIndex + count;
            int maxValueIndex = startIndex;
            T maxValue = arr[startIndex];

            for (int i = startIndex + 1; i < end; i++)
            {
                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }


        /// <summary>
        /// 查找Span中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(Span<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            T maxValue = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找Span中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(SpanZ<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            var ptr = arr.DataPtr;
            T maxValue = ptr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (ptr[i] > maxValue)
                {
                    maxValue = ptr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找Span中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(FlexibleArray<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            T maxValue = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找Span中最大值与最大值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMaxIndex<T>(ValueTypeFlexibleArray<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int maxValueIndex = 0;
            T maxValue = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(null, null, maxValue, maxValueIndex);
        }



        /// <summary>
        /// 查找T指针中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="ptr">数据指针</param>
        /// <param name="length">数据长度</param>
        /// <returns>结果</returns>
        unsafe public static MaxMinValueIndexInfo<T> FindMinIndex<T>(T* ptr, int length)
            where T : struct, INumber<T>
        {
            if (length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = ptr[0];

            for (int i = 1; i < length; i++)
            {
                if (ptr[i] < minValue)
                {
                    minValue = ptr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找T数组中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(IEnumerable<T> arr)
            where T : struct, INumber<T>
        {
            if (arr == null)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int length = arr.Count();
            if (length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr.ElementAt(0);

            for (int i = 1; i < length; i++)
            {
                if (arr.ElementAt(i) < minValue)
                {
                    minValue = arr.ElementAt(i);
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找T指针中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">查找的数据个数</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(IEnumerable<T> arr, int startIndex, int count)
            where T : struct, INumber<T>
        {
            if (arr == null || count < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int end = startIndex + count;
            int minValueIndex = startIndex;
            T minValue = arr.ElementAt(startIndex);

            for (int i = startIndex + 1; i < end; i++)
            {
                if (arr.ElementAt(i) < minValue)
                {
                    minValue = arr.ElementAt(i);
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找T数组中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(T[] arr)
            where T : struct, INumber<T>
        {
            if (arr == null)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];

            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找T指针中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">查找的数据个数</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(T[] arr, int startIndex, int count)
            where T : struct, INumber<T>
        {
            if (arr == null || count < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int end = startIndex + count;
            int minValueIndex = startIndex;
            T minValue = arr[startIndex];

            for (int i = startIndex + 1; i < end; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }


        /// <summary>
        /// 查找Span中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(Span<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找Span中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(SpanZ<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            var ptr = arr.DataPtr;
            T minValue = ptr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (ptr[i] < minValue)
                {
                    minValue = ptr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找Span中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(FlexibleArray<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }

        /// <summary>
        /// 查找Span中最小值与最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinIndex<T>(ValueTypeFlexibleArray<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, null, null);
        }



        /// <summary>
        /// 查找T指针中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="ptr">数据指针</param>
        /// <param name="length">数据长度</param>
        /// <returns>结果</returns>
        unsafe public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(T* ptr, int length)
            where T : struct, INumber<T>
        {
            if (length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = ptr[0];
            int maxValueIndex = 0;
            T maxValue = ptr[0];

            for (int i = 1; i < length; i++)
            {
                if (ptr[i] < minValue)
                {
                    minValue = ptr[i];
                    minValueIndex = i;
                }

                if (ptr[i] > maxValue)
                {
                    maxValue = ptr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T数组中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(IEnumerable<T> arr)
            where T : struct, INumber<T>
        {
            if (arr == null)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int length = arr.Count();
            if (length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr.ElementAt(0);
            int maxValueIndex = 0;
            T maxValue = arr.ElementAt(0);

            for (int i = 1; i < length; i++)
            {
                if (arr.ElementAt(i) < minValue)
                {
                    minValue = arr.ElementAt(i);
                    minValueIndex = i;
                }

                if (arr.ElementAt(i) > maxValue)
                {
                    maxValue = arr.ElementAt(i);
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T指针中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">查找的数据个数</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(IEnumerable<T> arr, int startIndex, int count)
            where T : struct, INumber<T>
        {
            if (arr == null || count < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int end = startIndex + count;
            int minValueIndex = startIndex;
            T minValue = arr.ElementAt(startIndex);
            int maxValueIndex = startIndex;
            T maxValue = arr.ElementAt(startIndex);

            for (int i = startIndex + 1; i < end; i++)
            {
                if (arr.ElementAt(i) < minValue)
                {
                    minValue = arr.ElementAt(i);
                    minValueIndex = i;
                }

                if (arr.ElementAt(i) > maxValue)
                {
                    maxValue = arr.ElementAt(i);
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }


        /// <summary>
        /// 查找T数组中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(T[] arr)
            where T : struct, INumber<T>
        {
            if (arr == null)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            int maxValueIndex = 0;
            T maxValue = arr[0];

            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }

                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找T指针中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">查找的数据个数</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(T[] arr, int startIndex, int count)
            where T : struct, INumber<T>
        {
            if (arr == null || count < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int end = startIndex + count;
            int minValueIndex = startIndex;
            T minValue = arr[startIndex];
            int maxValueIndex = startIndex;
            T maxValue = arr[startIndex];

            for (int i = startIndex + 1; i < end; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }

                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }


        /// <summary>
        /// 查找Span中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(Span<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            int maxValueIndex = 0;
            T maxValue = arr[0];

            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }

                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找Span中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(SpanZ<T> arr)
            where T : struct, INumber<T>
        {
            if (arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            int maxValueIndex = 0;
            T maxValue = arr[0];
            var ptr = arr.DataPtr;

            for (int i = 1; i < arr.Length; i++)
            {
                if (ptr[i] < minValue)
                {
                    minValue = ptr[i];
                    minValueIndex = i;
                }

                if (ptr[i] > maxValue)
                {
                    maxValue = ptr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }


        /// <summary>
        /// 查找Span中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(FlexibleArray<T> arr)
            where T : struct, INumber<T>
        {
            if (arr == null || arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            int maxValueIndex = 0;
            T maxValue = arr[0];

            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }

                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }

        /// <summary>
        /// 查找Span中最大最小值与最大最小值首次出现的索引
        /// </summary>
        /// <param name="arr">数据数组</param>
        /// <returns>结果</returns>
        public static MaxMinValueIndexInfo<T> FindMinMaxIndex<T>(ValueTypeFlexibleArray<T> arr)
            where T : struct, INumber<T>
        {
            if (arr == null || arr.Length < 1)
            {
                return new MaxMinValueIndexInfo<T>(null, null, null, null);
            }

            int minValueIndex = 0;
            T minValue = arr[0];
            int maxValueIndex = 0;
            T maxValue = arr[0];

            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < minValue)
                {
                    minValue = arr[i];
                    minValueIndex = i;
                }

                if (arr[i] > maxValue)
                {
                    maxValue = arr[i];
                    maxValueIndex = i;
                }
            }

            return new MaxMinValueIndexInfo<T>(minValue, minValueIndex, maxValue, maxValueIndex);
        }

    }
}
